﻿// 806 树上LCA2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <memory.h>

using  namespace std;
/*
http://oj.daimayuan.top/course/7/problem/534


给你一棵 n 个节点的以 1号节点为根的树，节点的编号为 1到 n。
现在有 m组询问，对于每组询问 u,v
，请求出 u号节点和 v 号节点的最近公共祖先。

输入格式
第一行一个整数 n表示节点数。

接下来 n−1行，每行两个整数 x,y表示 x 号节点和 y 号节点之间有一条边。

输入保证是一棵树。

接下来一行一个整数 m 表示询问数。

接下来 m 行，每行两个整数 u,v 表示一组询问。

输出格式
输出共 m 行，对于每组询问，输出一行一个整数表示对应的两个点的最近公共祖先的编号。

样例输入
4
1 2
1 3
3 4
2
1 2
2 4
样例输出
1
1



4
1 2
1 3
3 4
2
2 3
2 3

数据规模
对于所有数据，保证 1≤n,m≤100000,1≤u,v≤n。
*/



int n, m, father[100001][21], dist[100001];
vector<int> edges[100001];

void dfs(int x) {
	for (auto y : edges[x]) {
		dist[y] = dist[x] + 1;
		dfs(y);
	}
}


int main()
{
	scanf("%d",&n);
	for (int i = 1; i < n; i++) {
		int x, y;
		scanf("%d%d",&x,&y);
		edges[x].push_back(y);
		father[y][0] = x;
	}
	for (int i = 1; i <= 20; i++) {
		for (int j = 1; j <= n; j++) {
			if (father[j][i - 1])
				father[j][i] = father[father[j][i - 1]][i - 1];
		}
	}
	memset(dist, 0, sizeof dist);
	dfs(1);
	scanf("%d",&m);
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d",&x,&y);
		if (dist[x] < dist[y])
			swap(x, y);
		int z = dist[x] - dist[y];
		for (int j = 0; j <= 20 && z; j++, z /= 2) {
			if (z & 1)
				x = father[x][j];
		}

		if (x == y) {
			printf("%d\n",x);
			continue;
		}
		 
		for (int j = 20; j >= 0; j--) {
			if (father[x][j] != father[y][j]) {
				x = father[x][j], y = father[y][j];
			}
		}
		printf("%d\n",father[x][0]);
	}

	return 0;
}
